/**
 *  学习目标：Todos 案例
 *    1. 类组件改造成函数组件
 *    2. 拆分函数组件(头部，主体，底部)
 *    3. 初始化列表数据，并渲染到主体组件中
 *    4. 主体 - 根据 id 删除数据
 *    5. 主体 - 根据 id 更新完成状态
 *    6. 底部 - 删除已完成任务
 *    7. 底部 - 计算剩余任务数量
 *    8. 底部 - 高亮切换效果
 *    9. 底部 - 切换显示列表(全部显示/未完成/已完成)
 *    10. 头部 - 受控组件，获取数据，按回车键，新增待办任务
 *    11. 主体 - 计算全选状态，切换全选状态
 *    学习完 useEffect() 后，再实现以下两个功能
 *    12. 组件挂载时 - 获取本地存储数据
 *    13. 数据更新时 - 设置本地存储数据
 */
import React, { useEffect, useState } from 'react'
import './styles/base.css'
import './styles/index.css'

export default function App() {
  const [list, setList] = useState([
    { id: 1, content: '吃饭', done: false },
    { id: 2, content: '睡觉', done: true },
    { id: 3, content: '打代码', done: false },
  ])

  const [type, setType] = useState('all')

  // 组件挂载时 - 获取本地存储数据
  useEffect(() => {
    console.log('组件挂载时 - 获取本地存储数据')
    setList(JSON.parse(localStorage.getItem('todos')))
    setType(localStorage.getItem('todos-type'))
  }, [])

  // 数据更新时 - 设置本地存储数据
  useEffect(() => {
    console.log('数据更新时 - 设置本地存储数据')
    localStorage.setItem('todos', JSON.stringify(list))
    localStorage.setItem('todos-type', type)
  }, [list, type])

  // 根据 id 删除数据
  const handelDelById = (id) => {
    // 使用新数据覆盖旧数据
    setList(list.filter((v) => v.id !== id))
  }

  // 根据 id 更新完成状态
  const handleChangeDoneById = (id) => {
    // 准备新数据
    const newList = list.map((item) => {
      if (item.id === id) {
        return {
          ...item,
          done: !item.done,
        }
      } else {
        return item
      }
    })
    // 使用新数据覆盖旧数据
    setList(newList)
  }

  // 删除已完成任务
  const handleClear = () => {
    setList(list.filter((v) => !v.done))
  }

  // 修改 type 高亮切换效果
  const handleChangeType = (type) => {
    setType(type)
  }

  // 新增待办任务
  const handleAddTodo = (content) => {
    setList([{ id: new Date(), content: content, done: false }, ...list])
  }

  const checkAllChange = (ckecked) => {
    setList(
      list.map((item) => {
        return {
          ...item,
          done: ckecked,
        }
      }),
    )
  }

  return (
    <section className='todoapp'>
      {/* 头部 */}
      <Header handleAddTodo={handleAddTodo} />
      {/* 主体 */}
      <Main
        type={type}
        list={list}
        handelDelById={handelDelById}
        handleChangeDoneById={handleChangeDoneById}
        checkAllChange={checkAllChange}
      />
      {/* 底部 */}
      <Footer
        type={type}
        list={list}
        handleClear={handleClear}
        handleChangeType={handleChangeType}
      />
    </section>
  )
}

// 头部组件
function Header({ handleAddTodo }) {
  // 用于收集表单数据用的
  const [content, setContent] = useState('')

  // 用户键盘弹起
  const onKeyUp = (e) => {
    // console.log(e.key)
    // 如果按回车键
    if (e.key === 'Enter') {
      // 非空判断
      if (content.trim() === '') return alert('请输入内容...')
      // console.log('通知父组件添加待办事项')
      handleAddTodo(content)
      // 发布成功后清空
      setContent('')
    } else if (e.key === 'Escape') {
      // 按 Esc 键清空输入
      setContent('')
    }
  }

  return (
    <header className='header'>
      <h1>todos</h1>
      <input
        className='new-todo'
        value={content}
        onChange={(e) => setContent(e.target.value)}
        onKeyUp={onKeyUp}
        placeholder='What needs to be done?'
        autoFocus
      />
    </header>
  )
}

// 主体组件
function Main({ type, list, handelDelById, handleChangeDoneById, checkAllChange }) {
  // 根据 type 计算要展示的列表数据
  let showList = list
  if (type === 'active') {
    showList = list.filter((v) => !v.done)
  } else if (type === 'completed') {
    showList = list.filter((v) => v.done)
  }

  // 计算全选状态
  const checkAll = list.length !== 0 && list.every((v) => v.done)

  return (
    <section className='main'>
      <input
        className='toggle-all'
        checked={checkAll}
        onChange={() => checkAllChange(!checkAll)}
        type='checkbox'
        id='toggle-all'
      />
      <label htmlFor='toggle-all'>Mark all as complete</label>
      <ul className='todo-list'>
        {showList.map((item) => (
          <li key={item.id} className={item.done ? 'completed' : ''}>
            <div className='view'>
              <input
                className='toggle'
                checked={item.done}
                onChange={() => handleChangeDoneById(item.id)}
                type='checkbox'
              />
              <label>{item.content}</label>
              <button onClick={() => handelDelById(item.id)} className='destroy'></button>
            </div>
            <input className='edit' />
          </li>
        ))}
      </ul>
    </section>
  )
}

// 底部组件
function Footer({ list, handleClear, type, handleChangeType }) {
  // 计算剩余任务数量
  const leftCount = list.filter((v) => !v.done).length
  return (
    <footer className='footer'>
      <span className='todo-count'>
        <strong>{leftCount}</strong> item left
      </span>
      <ul className='filters'>
        <li>
          <a
            onClick={() => handleChangeType('all')}
            className={type === 'all' ? 'selected' : ''}
            href='#/'
          >
            All
          </a>
        </li>
        <li>
          <a
            onClick={() => handleChangeType('active')}
            className={type === 'active' ? 'selected' : ''}
            href='#/active'
          >
            Active
          </a>
        </li>
        <li>
          <a
            onClick={() => handleChangeType('completed')}
            className={type === 'completed' ? 'selected' : ''}
            href='#/completed'
          >
            Completed
          </a>
        </li>
      </ul>
      <button onClick={handleClear} className='clear-completed'>
        Clear completed
      </button>
    </footer>
  )
}
